package message.messageFactory;

import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import message.AddServerRequestMessage;
import message.AddServerResponseMessage;
import message.AuthenticationRequestMessage;
import message.AuthenticationResponseMessage;
import message.InsertDataRequestMessage;
import message.InsertDataResponseMessage;
import message.PingClientResponseMessage;
import message.PingServerResponseMessage;
import message.PingServerResponseMessage.ServerStatus;
import message.RestartServerRequestMessage;
import message.RestartServerResponseMessage;
import message.ShutDownServerRequestMessage;
import message.ShutDownServerResponseMessage;
import message.UpdateDataRequestMessage;
import message.UpdateDataResponseMessage;

import org.junit.Test;

public class MessageFactoryTest
{
	private final MessageFactory factory;
	
	public MessageFactoryTest() throws InstantiationException
	{
		factory = MessageFactory.getInstance();
	}
	
	private String getFileContents(String fileName) throws FileNotFoundException
	{
		StringBuilder builder = new StringBuilder();
		BufferedReader reader = new BufferedReader(new FileReader(fileName));
		
		try
		{
			while (reader.ready())
			{
				builder.append(reader.readLine());
				builder.append("\r\n");
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		return builder.toString();
	}
	private String removeBreaksAndTabs(String str)
	{
		return str.replace("\r", "").replace("\n", "").replace("\t", "");
	}
	private String removeBreakAndTabsFromFileContent(String fileName) throws FileNotFoundException
	{
		return removeBreaksAndTabs(getFileContents(fileName));
	}
	@Test
	public void testSerializeAddServerRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/addServerRequestMessage.xml");
		AddServerRequestMessage message = new AddServerRequestMessage();
		
		message.setIpAddress("127.0.0.1");
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeAddServerResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/addServerResponseMessage.xml");
		AddServerResponseMessage message = new AddServerResponseMessage();
		
		message.addIP("127.0.0.1");
		message.addIP("127.0.0.1");
		message.addIP("127.0.0.1");
		message.addIP("127.0.0.1");
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeAuthenticationRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/AuthenticationRequestMessage.xml");
		AuthenticationRequestMessage message = new AuthenticationRequestMessage();
		
		message.setUsername("Username");
		message.setPassword("Password");
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeAuthenticationResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/AuthenticationResponseMessage.xml");
		AuthenticationResponseMessage message = new AuthenticationResponseMessage();
		
		message.setSuccess(true);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeInsertDataRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/insertDataRequestMessage.xml");
		InsertDataRequestMessage message = new InsertDataRequestMessage();
		
		message.setId(1);
		message.setUsername("Username");
		message.setDateCreated(0);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeInsertDataResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/insertDataResponseMessage.xml");
		InsertDataResponseMessage message = new InsertDataResponseMessage();
		
		message.setSuccess(true);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializePingClientResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/pingClientResponseMessage.xml");
		PingClientResponseMessage message = new PingClientResponseMessage();
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializePingRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/pingClientResponseMessage.xml");
		PingClientResponseMessage message = new PingClientResponseMessage();
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializePingServerResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/pingServerResponseMessage.xml");
		PingServerResponseMessage message = new PingServerResponseMessage();
		
		message.setStatus(ServerStatus.Initiating);
		message.setTimeIntiated(0);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeRestartServerRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/restartServerRequestMessage.xml");
		RestartServerRequestMessage message = new RestartServerRequestMessage();
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeRestartServerResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/restartServerResponseMessage.xml");
		RestartServerResponseMessage message = new RestartServerResponseMessage();
		
		message.setRestarting(true);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeShutDownServerRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/shutDownRequestMessage.xml");
		ShutDownServerRequestMessage message = new ShutDownServerRequestMessage();
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeShutDownServerResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/shutDownResponseMessage.xml");
		ShutDownServerResponseMessage message = new ShutDownServerResponseMessage();
		
		message.setShuttingDown(true);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeUpdateDataRequestMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/updateDataRequestMessage.xml");
		UpdateDataRequestMessage message = new UpdateDataRequestMessage();
		
		message.setId(1);
		message.setUsername("Username");
		message.setPassword("Password");
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testSerializeUpdateDataResponseMessage() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/valid/updateDataResponseMessage.xml");
		UpdateDataResponseMessage message = new UpdateDataResponseMessage();
		
		message.setSuccess(true);
		
		String serialized = factory.serializeMessage(message);
		assertEquals(fileContents, serialized);
	}
	@Test
	public void testInvalidUnserializeSyntax() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/invalid/authenticationRequestMessage.xml");
		
		assertEquals(null, factory.unserializeMessage(fileContents));
	}
	@Test
	public void testInvalidUnserializeType() throws FileNotFoundException
	{
		String fileContents = removeBreakAndTabsFromFileContent("testFiles/messageXML/invalid/authenticationResponseMessage.xml");
		AuthenticationResponseMessage message = new AuthenticationResponseMessage();
		
		message.setSuccess(false);
		
		assertEquals(message, factory.unserializeMessage(fileContents));
	}
}
